﻿Imports System.Text
Imports System.Globalization
Imports Com.SharpZebra.Printing
Imports System.Text.RegularExpressions

Public Class CommonClass
    Public Shared Sub printLabel(textString() As String)
        Dim sb As StringBuilder
        Dim sbLowerTag As StringBuilder

        sbLowerTag = New StringBuilder
        sb = New StringBuilder

        Dim appendToLowerTag As Boolean = True

        Try
            sb.AppendLine()
            sb.AppendLine("N") ' clear 
            sb.AppendLine("ZB") 'ZT - print orientation
            sb.AppendLine("q" & My.Settings.LabelWidth * 203) '3 7/8 inch x 203 dpi = 786.625 width
            sb.AppendLine("Q" & My.Settings.LabelLength * 203 & ",26") ' 8 inch x 203 dpi = 1624 length - 26 dot gap between labels, printer should detect this automatically
            sb.AppendLine("D" & My.Settings.Density) 'print density

            Dim txtSeparatorString As String = My.Settings.separatorString
            Dim textWrapCtr As Integer = My.Settings.textWrapCtr
            Dim xCoord As Integer = My.Settings.xcoord

            Dim yCoord As Integer = My.Settings.ycoord
            Dim yCoordAppend As Integer = My.Settings.yCoordAppend
            Dim topLabelFont As Integer = My.Settings.TopPartFont

            Dim origyCoordLowerTag As Integer = My.Settings.yCoordLowerTag
            Dim yCoordLowerTag As Integer = My.Settings.yCoordLowerTag
            Dim yCoordLowerAppend As Integer = My.Settings.yCoordLowerAppend
            Dim lowerLabelFont As Integer = My.Settings.LowPartFont

            Dim emailSeparatorFound As Boolean = False

            Dim textWrapping As List(Of String)

            For Each item In textString
                'Check for separator string to stop populating the stringbuilder that prints the lower part of the label
                'If separator string is encountered then stop populating the stringbuilder for printing of the lower label
                'any text (including the separator) after should not be printed on the lower part
                If item.ToString.Contains(txtSeparatorString) Then
                    appendToLowerTag = False
                    emailSeparatorFound = True
                End If

                'wrap text if necessary
                textWrapping = WrapText(Trim(item.ToString), textWrapCtr)
                If textWrapping.Count > 1 Then
                    For Each lineItem In textWrapping
                        If yCoord < origyCoordLowerTag - 150 Then
                            sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "A" & xCoord & "," & yCoord & ",0," & topLabelFont & ",1,1,N,""" & lineItem.ToString & """"))
                            yCoord += yCoordAppend
                        End If

                        If appendToLowerTag Then
                            sbLowerTag.AppendLine(String.Format(CultureInfo.InvariantCulture, "A" & xCoord & "," & yCoordLowerTag & ",0," & lowerLabelFont & ",2,2,N,""" & lineItem.ToString & """"))
                            yCoordLowerTag += yCoordLowerAppend
                        End If
                    Next
                Else
                    If yCoord < origyCoordLowerTag - 150 Then
                        sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "A" & xCoord & "," & yCoord & ",0," & topLabelFont & ",1,1,N,""" & Trim(item.ToString) & """"))
                        yCoord += yCoordAppend
                    End If

                    If appendToLowerTag Then
                        sbLowerTag.AppendLine(String.Format(CultureInfo.InvariantCulture, "A" & xCoord & "," & yCoordLowerTag & ",0," & lowerLabelFont & ",2,2,N,""" & item.ToString & """"))
                        yCoordLowerTag += yCoordLowerAppend
                    End If
                End If
            Next
            sb.Append(sbLowerTag.ToString)
            sb.AppendLine("P1, 1") ' print labels - 1 copy

            If Not emailSeparatorFound Then 'throw error, the separator string was not found inside the email body
                Throw New Exception("Email body separator not found. Please check label printer configuration.")
            End If

            Dim selectedPrinterName As String = DefaultPrinterName() 'printer.DefaultZebraPrinter()
            Dim z As New ZebraPrinter(selectedPrinterName)
            z.Print(sb.ToString)
        Catch ex As Exception
            WriteToEventLog(ex.Message.ToString & ControlChars.Lf & ControlChars.Lf & If(Not ex.InnerException Is Nothing, ex.InnerException.ToString, "No inner exception noted."))
        End Try
    End Sub

    Public Shared Function DefaultPrinterName() As String
        Dim oPS As New System.Drawing.Printing.PrinterSettings
        Try
            DefaultPrinterName = oPS.PrinterName
        Catch ex As System.Exception
            DefaultPrinterName = ""
        Finally
            oPS = Nothing
        End Try
    End Function

    Public Shared Function StripTags(ByVal html As String) As String
        ' Remove HTML tags.
        Return Regex.Replace(html, "<.*?>", "")
    End Function

    Public Shared Function WrapText(ByVal Text As String, ByVal LineLength As Integer) As List(Of String)
        Dim ReturnValue As New List(Of String)
        ' Remove leading and trailing spaces
        Text = Trim(Text)


        Dim Words As String() = Text.Split(" ")

        If Words.Length = 1 And Words(0).Length > LineLength Then
            ' Text is just one big word that is longer than one line
            ' Split it mercilessly
            Dim lines As Integer = (Int(Text.Length / LineLength) + 1)
            Text = Text.PadRight(lines * LineLength)
            For i = 0 To lines - 1
                Dim SliceStart As Integer = i * LineLength
                ReturnValue.Add(Text.Substring(SliceStart,
                LineLength))
            Next
        Else
            Dim CurrentLine As New System.Text.StringBuilder
            For Each Word As String In Words
                ' will this word fit on the current line?
                If CurrentLine.Length + Word.Length <
                LineLength Then
                    CurrentLine.Append(Word & " ")
                Else
                    ' is the word too long for one line
                    If Word.Length > LineLength Then
                        ' hack off the first piece, fill out the current line and start a new line
                        Dim Slice As String =
                        Word.Substring(0, LineLength - CurrentLine.Length)
                        CurrentLine.Append(Slice)
                        ReturnValue.Add(CurrentLine.ToString)
                        CurrentLine = New System.Text.StringBuilder()

                        ' Remove the first slice from the word
                        Word = Word.Substring(Slice.Length,
                        Word.Length - Slice.Length)

                        ' How many more lines do we need for this word?
                        Dim RemainingSlices As Integer =
                        Int(Word.Length / LineLength) + 1
                        For LineNumber = 1 To RemainingSlices
                            If LineNumber = RemainingSlices Then

                                'this is the last slice
                                CurrentLine.Append(Word & " ")
                            Else
                                ' this is not the last slice
                                ' hack off a slice that is one line long, add that slice
                                ' to the output as a line and start a new line
                                Slice = Word.Substring(0,
                                LineLength)
                                CurrentLine.Append(Slice)

                                ReturnValue.Add(CurrentLine.ToString)
                                CurrentLine = New System.Text.StringBuilder()

                                ' Remove the slice from the  Word()
                                Word = Word.Substring(Slice.Length, Word.Length - Slice.Length)
                            End If
                        Next
                    Else
                        ' finish the current line and start a new one with the wrapped word
                        ReturnValue.Add(CurrentLine.ToString)
                        CurrentLine = New System.Text.StringBuilder(Word & " ")
                    End If
                End If
            Next

            ' Write the last line to the output
            If CurrentLine.Length > 0 Then
                ReturnValue.Add(CurrentLine.ToString)
            End If
        End If
        Return ReturnValue
    End Function



    Public Shared Function WriteToEventLog(ByVal Entry As String, _
     Optional ByVal AppName As String = "Zebra_Printing", _
     Optional ByVal EventType As  _
     EventLogEntryType = EventLogEntryType.Information, _
     Optional ByVal LogName As String = "Application") As Boolean

        '*************************************************************
        'PURPOSE: Write Entry to Event Log using VB.NET
        'PARAMETERS: Entry - Value to Write
        '            AppName - Name of Client Application. Needed 
        '              because before writing to event log, you must 
        '              have a named EventLog source. 
        '            EventType - Entry Type, from EventLogEntryType 
        '              Structure e.g., EventLogEntryType.Warning, 
        '              EventLogEntryType.Error
        '            LogName: Name of Log (System, Application; 
        '              Security is read-only) If you 
        '              specify a non-existent log, the log will be
        '              created

        'RETURNS:   True if successful, false if not

        'EXAMPLES: 
        '1. Simple Example, Accepting All Defaults
        '    WriteToEventLog "Hello Event Log"

        '2.  Specify EventSource, EventType, and LogName
        '    WriteToEventLog("Danger, Danger, Danger", "MyVbApp", _
        '                      EventLogEntryType.Warning, "System")
        '
        'NOTE:     EventSources are tightly tied to their log. 
        '          So don't use the same source name for different 
        '          logs, and vice versa
        '******************************************************

        Dim objEventLog As New EventLog()

        Try
            'Register the App as an Event Source
            If Not objEventLog.SourceExists(AppName) Then

                objEventLog.CreateEventSource(AppName, LogName)
            End If
            'objEventLog.Log = "TEST"
            objEventLog.Source = AppName

            'WriteEntry is overloaded; this is one
            'of 10 ways to call it
            objEventLog.WriteEntry(Entry, EventType)
            Return True
        Catch Ex As Exception
            Return False

        End Try

    End Function

End Class
